using System.Diagnostics;
using Godot;
using ZFramework;

namespace PaintAWorld.Gd
{
    [GlobalClass]
    public partial class VoxelModelInstance : MeshInstance3D
    {
        public bool Regen(VoxelModel data, Vector3 offset, float voxelSize)
        {
            Debug.Assert(data != null);

            Mesh ??= new ArrayMesh();
            var mesh = Mesh as ArrayMesh;

            mesh.ClearSurfaces();

            var builder = new MeshBuilder();

            unsafe
            {
                var xOffset = stackalloc int[] { -1, 1, 0, 0, 0, 0 };
                var yOffset = stackalloc int[] { 0, 0, -1, 1, 0, 0 };
                var zOffset = stackalloc int[] { 0, 0, 0, 0, -1, 1 };
                var facings = stackalloc Facing[] { Facing.West, Facing.East, Facing.Down, Facing.Up, Facing.North, Facing.South };

                for (var z = 0; z < data.Length; z++)
                {
                    for (var y = 0; y < data.Height; y++)
                    {
                        for (var x = 0; x < data.Width; x++)
                        {
                            if (!data.HasVoxel(x, y, z))
                                continue;

                            var facing = Facing.All;
                            for (var i = 0; i < 6; i++)
                            {
                                if (data.HasVoxel(x + xOffset[i], y + yOffset[i], z + zOffset[i]))
                                {
                                    facing &= ~facings[i];
                                }
                            }
                            builder.AddCube(x, y, z, offset, voxelSize, facing, data.ColorAt(x, y, z));
                        }
                    }
                }
            }

            if (!builder.IsEmpty)
            {
                var arrays = new Godot.Collections.Array();

                builder.Build(ref arrays);

                mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
                return true;
            }
            else
            {
                return false;
            }
        }

        public void RegenCollider()
        {
            foreach (var child in GetChildren())
            {
                child.QueueFree();
            }
            CreateTrimeshCollision();
        }
    }

}